/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.sdcache.distributed.server;

import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 *
 * @author chaitanya
 */
public class ClientHandler extends Thread
{

    Socket socket;
    private Receiver receiver;
    private Sender sender;
    private  boolean running;
    private String ping;
    private String regTag;
    private  BlockingQueue inQ;
    private  BlockingQueue outQ;
    private RequestHandler handler[];
    int noOfRequestHandler;
    
    public ClientHandler(String name,Socket socket)
    {
        this(name,socket,1);
    }
    public ClientHandler(String name,Socket socket, int noOfRequestHandler)
    {
        this.socket=socket;
        this.noOfRequestHandler=noOfRequestHandler;
        inQ= new LinkedBlockingQueue<String>();
        outQ= new LinkedBlockingQueue<String>();
        setName(name);
    }
    public void startProcessing(Processor processor)
    {
        handler= new RequestHandler[noOfRequestHandler];
        start();
        for(int i=0;i<noOfRequestHandler;i++)
        {
            handler[i]= new RequestHandler(getName(), this,processor);
            handler[i].start();
        }
    }
    
    @Override
    public void run()
    {
        connect();
        while(running)
        {
            try{
                Thread.sleep(5000);
            }catch(Exception e)
            {
                e.printStackTrace();
            }
        }
        disconnect();
    }
  /**
     * Connect to The client
     */
    private void connect()
    {
        try
        {

            receiver = new Receiver(this.getName(),socket,this);
            sender = new Sender(this.getName(),socket,this);

            running=true;
            try
            {
                receiver.start();
            } catch (IllegalThreadStateException itse)
            {
                itse.printStackTrace();
            }

            try
            {
                sender.start();
            } catch (IllegalThreadStateException itse)
            {
                itse.printStackTrace();
            }
        }
        /*	try {		        
        System.out.println(" ******Before the sockettrdServer ***** ");
        thread.start();
        }catch(IllegalThreadStateException itse) {
        itse.printStackTrace();
        log.logMessage("SocketConnection","SocketInterface::connect() IllegalThreadStateException while starting Sender: " + itse.toString(),"Debug");
        }*/
        catch (Exception e)
        {
            disconnect();
        }
    }

    public void disconnect()
    {
        try
        {
            try
            {
                receiver.join();
                sender.join();
            } catch (InterruptedException ie)
            {

            } catch (Exception e)
            {
            }

            if (socket != null)
            {
                socket.close();
            }

        } catch (IOException ioe)
        {
        } finally
        {
            socket = null;
        }
    }
    public void log(String message,String id)
    {
       // System.out.println(message+"   "+id);
      //  log.logMessage(getName(), message, id);
    }
    
    public void setPing(String str)
    {
        this.ping=str;
    }

    public void setRegTag(String regTag)
    {
        this.regTag = regTag;
    }
        public BlockingQueue<String> getInQ()
    {
        return inQ;
    }
    public BlockingQueue<String> getOutQ()
    {
        return outQ;
    }
            
     public  void sendObject(Object object)
    {
        try
        {
            outQ.put(object);
        } catch (InterruptedException ex)
        {
        }
    }
    
    public Object getObject()
    {
        Object str = null;
        try
        {
            str = inQ.take();
        } catch (InterruptedException ex)
        {
        }
        return str;
    }

    public void setRunning(boolean running)
    {
        this.running = running;
    }

    public boolean isRunning()
    {
        return running;
    }
    
}
